﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using NTweet.HttpService;
using System.Net;
using Moq.Language;
using NTweet.LocalCacheService;

namespace Tests.NTweet.Core {
	public abstract class ClientTestHarness {
		public TestContext TestContext { get; set; }

		CookieContainer cookieContainer;

		List<Mock> allMocks = new List<Mock>();
		protected Mock<ILocalRepository> localRepository;
		protected Mock<IHttpRequestFactory> httpRequestFactory;
		protected Mock<ICredentials> credentials;

		protected Mock<T> Mock<T>() where T : class {
			var result = new Mock<T>(MockBehavior.Strict);
			allMocks.Add(result);
			return result;
		}

		[TestInitialize]
		public virtual void CreateMocks() {
			allMocks.Clear();
			localRepository = Mock<ILocalRepository>();
			httpRequestFactory = Mock<IHttpRequestFactory>();
			httpRequestFactory.SetupProperty((f) => f.DefaultCredentials, null);
			httpRequestFactory.SetupProperty((f) => f.DefaultCookieContainer, null);
			credentials = Mock<ICredentials>();
		}

		[TestCleanup]
		public virtual void VerifyMocks() {
			foreach (var item in allMocks) {
				item.VerifyAll();
			}
		}

		protected Mock<IHttpResponse> CreateHttpRequestMock(string uri) {
			Mock<IHttpRequest> request;
			return CreateHttpRequestMock(uri, out request);
		}

		protected Mock<IHttpResponse> CreateHttpRequestMock(string uri, out Mock<IHttpRequest> request) {
			request = Mock<IHttpRequest>();
			Mock<IHttpResponse> response = Mock<IHttpResponse>();
			var list = new List<IVerifies>();
			httpRequestFactory
				.Setup((f) => f.CreateRequest(uri))
				.Returns(request.Object)
				.Verifiable();
			request
				.SetupSet((r) => r.Credentials)
				.Callback((c) => Assert.AreSame(credentials.Object, c))
				.Verifiable();
			request
				.Setup((r) => r.GetResponse())
				.Returns(response.Object)
				.Verifiable();
			allMocks.Add(request);
			allMocks.Add(response);
			return response;
		}
	}
}
